#include <QUrl>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QFile>
#include <QDir>

#include "filedownloader.h"
#include "utils.h"

namespace Jcr
{

class FileDownloaderPrivate
{
public:
    QUrl url;
    QString saveDir;
    QString saveName;
    bool isAborted = false;
    QNetworkAccessManager* netMgr = nullptr;
    QNetworkReply* reply = nullptr;
};

FileDownloader::FileDownloader(QObject *parent) : QObject(parent)
{
    d_ptr = new FileDownloaderPrivate;
}

FileDownloader::FileDownloader(const QUrl &url, QObject *parent) : QObject(parent)
{
    d_ptr = new FileDownloaderPrivate;
    d_ptr->url = url;
}

FileDownloader::~FileDownloader()
{
    delete d_ptr;
}

void FileDownloader::setUrl(const QUrl& url)
{
    d_ptr->url = url;
}

QUrl FileDownloader::url() const
{
    return d_ptr->url;
}

void FileDownloader::setSaveDir(const QString& saveDir)
{
    if (d_ptr->saveDir != saveDir)
        d_ptr->saveDir = saveDir;
}

QString FileDownloader::saveDir() const
{
    return d_ptr->saveDir;
}

void FileDownloader::setSaveName(const QString& saveName)
{
    if (d_ptr->saveName != saveName)
        d_ptr->saveName = saveName;
}

QString FileDownloader::saveName() const
{
    return d_ptr->saveName;
}

QString FileDownloader::localPath() const
{
    QString imageName;
    if (d_ptr->saveName.isEmpty())
        imageName = Jcr::Utils::fileNameFromUrl(d_ptr->url);
    else
        imageName = QString("%1.%2").arg(d_ptr->saveName).arg(Jcr::Utils::fileExtFromUrl(d_ptr->url));

    QString imageFile = QDir::toNativeSeparators(d_ptr->saveDir + "/" + imageName);
    imageFile.replace("\\\\", "\\");
    return imageFile;
}

void FileDownloader::start()
{
    if (d_ptr->url.isEmpty()) {
        emit finished();
        return;
    }

    if (!d_ptr->netMgr) {
        d_ptr->netMgr = new QNetworkAccessManager(this);
        connect(d_ptr->netMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(onReply(QNetworkReply*)));
    }

    QNetworkRequest request;
    request.setUrl(d_ptr->url);
    d_ptr->reply = d_ptr->netMgr->get(request);
    connect(d_ptr->reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(onDownloadProgress(qint64,qint64)));
}

void FileDownloader::abort()
{
    if (d_ptr->reply) {
        d_ptr->reply->abort();
        emit percentCompleted(0);
    }
}

void FileDownloader::onReply(QNetworkReply *reply)
{
    QFile file;
    file.setFileName(localPath());
    if (!file.open(QIODevice::WriteOnly)) {
        qDebug() << "Failed to open file to write { code:" << file.error() << " desc: " << file.errorString() << "}";
        emit finished();
        return;
    }

    QByteArray result = reply->readAll();
    file.write(result);
    file.close();
    emit finished();

//    deleteLater();
}

void FileDownloader::onDownloadProgress(qint64 receivedBytes, qint64 totalBytes)
{
    emit percentCompleted((float)receivedBytes / totalBytes);
}


} // namespace
